#include <cassert>
#include <cstddef>
#include <iostream>
#include <typeinfo>
#include <utility>
#include <any>
using namespace std;
class Any {
    private:
        class holder {
            public:
                virtual ~holder() {}
                virtual const type_info& type() = 0;
                virtual holder* clone() = 0;
        };
        template<class T>
        class placeholder : public holder {
            public:
                placeholder(const T& val)
                :_val(val) {}
                virtual const type_info& type() {
                    return typeid(T);
                }
                virtual holder* clone() {
                    return new placeholder(_val);
                }
            public:
                T _val;
        };
    private:
        holder* _content;
    public:
        Any(): _content(NULL) {}
        template<typename T>
        Any(const T& val) : _content(new placeholder<T>(val)) {}
        Any(const Any& other) : _content(other._content ? other._content->clone() : NULL) {}
        ~Any() {
            delete _content;
        }
        Any& swap(Any& other) {
            std::swap(_content, other._content);
            return *this;
        }
        template<class T>
        T* get() {
            assert(typeid(T) == _content->type());
            return &((placeholder<T>*)_content)->_val; 
            // 这里直接不返回值的几个原因：
            // 1、性能问题，可能值本身比较大不好返回（消耗大）
            // 2、安全问题，不匹配时无法安全返回了
            // 3、和库里面的保持一致
        }
        template<class T>
        Any& operator=(const T& val) {
            Any(val).swap(*this);
            return *this;
        }
        Any& operator=(const Any& other) {
            Any(other).swap(*this);
            return *this;
        }
};
class Test {
public:
    Test() {
        cout << "我是构造函数！" << endl;
    }
    ~Test() {
        cout << "我是析构函数！" << endl;
    }
    Test(const Test& t) {
        cout << "我是拷贝构造函数！" << endl;
    }
};
int main() {
    // Any a;
    // {
    //     Test t;
    //     a = t;
    // }
    // a = 10;
    // int* ptr = a.get<int>();
    // cout << *ptr << endl;
    // a = string("hello");
    // string* ptr = a.get<string>();
    // cout << *ptr << endl;



    // 库里面的实现
    any a;
    a = 10;
    int* ptri = any_cast<int>(&a);
    cout << *ptri << endl;
    a = string("hello");
    string* ptrs = any_cast<string>(&a);
    cout << *ptrs << endl;
    return 0;
}